package com.hgyc.mom.tool.strategy;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hgyc.mom.common.util.DateUtils;
import com.hgyc.mom.tool.entity.AutoCodePart;
import com.hgyc.mom.tool.entity.AutoCodeResult;
import com.hgyc.mom.tool.enums.CycleMethodEnum;
import com.hgyc.mom.tool.service.AutoCodeResultService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 编码规则组成序列号生成实现类
 * @author fwj
 * @since 2025/5/8
 */
@Component
@Order(3)
public class PartTypeSerialNoHandler implements PartTypeTemplate{

    @Autowired
    private AutoCodeResultService autoCodeResultService;

    @Override
    public String partHandle(AutoCodePart autoCodePart) {
        String method = autoCodePart.getCycleMethod();
        String param ="";
        if(CycleMethodEnum.CYCLE_METHOD_OTHER.getCode().equals(method)){
            param = autoCodePart.getInputCharacter();
        }else{
            switch (CycleMethodEnum.getByCode(method)){
                case CYCLE_METHOD_YEAR:
                    param = DateUtils.format(LocalDateTime.now(),"yyyy");
                    break;
                case CYCLE_METHOD_MONTH:
                    param = DateUtils.format(LocalDateTime.now(),"yyyyMM");
                    break;
                case CYCLE_METHOD_DAY:
                    param = DateUtils.format(LocalDateTime.now(),"yyyyMMdd");
                    break;
                case CYCLE_METHOD_HOUR:
                    param = DateUtils.format(LocalDateTime.now(),"yyyyMMddHH");
                    break;
                case CYCLE_METHOD_MINUTE:
                    param = DateUtils.format(LocalDateTime.now(),"yyyyMMddHHmm");
                    break;
                default:
                    break;
            }
        }

        List<AutoCodeResult> rs = getAutoCodeResult(autoCodePart.getRuleId(),param,method);
        if(!rs.isEmpty()){
            //如果在编码记录表中有记录，则在最后一个流水号上加上步长，返回新的流水号
            AutoCodeUtil.threadLocal.set(false);
            Long lastSerialNo = rs.get(0).getLastSerialNo();
            return String.format("%0"+autoCodePart.getPartLength()+"d",lastSerialNo+autoCodePart.getSerialStep());
        }else {
            //如果在编码记录表中不存在，则直接返回起始流水号
            AutoCodeUtil.threadLocal.set(true);
            return String.format("%0"+autoCodePart.getPartLength()+"d",autoCodePart.getSerialStartNo());
        }
    }

    //从编码结果记录表中查找当前指定循环规则的流水号记录
    private List<AutoCodeResult> getAutoCodeResult(Long ruleId, String param, String cycleMethod){
        LambdaQueryWrapper<AutoCodeResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AutoCodeResult::getRuleId, ruleId);
        //这里的param将按照 gen_date like #{param}+'%' 的方式进行模糊查询，数据库中记录的永远都是yyyMMddHHmmss格式的
        queryWrapper.likeRight(AutoCodeResult::getGenDate, param);
        return autoCodeResultService.list(queryWrapper);
    }
}
